package com.zpeb.pdd.ws;

import com.zpeb.pdd.config.getHttpSessionConfig;
import com.zpeb.pdd.entity.Chat;
import com.zpeb.pdd.mapper.ChatMapper;
import com.zpeb.pdd.mapper.FriendMapper;
import com.zpeb.pdd.utils.CommonUtils;
import com.zpeb.pdd.utils.Msg;
import com.zpeb.pdd.utils.ServerEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;


/**
 * @author VX5
 * @Title: MJC
 * @ProjectName judge-sql
 * @Description: TODO 实现服务端主动向客户端推送消息
 * @date ${DAT}12:57
 */
@ServerEndpoint(value = "/chat/{id}",configurator = getHttpSessionConfig.class,encoders ={ServerEncoder.class})
@Component
public class WebSocket {

    private Logger logger = LoggerFactory.getLogger(WebSocket.class);
    public static ChatMapper chatMapper;
    public static FriendMapper friendMapper;
    //存放每个客户端的对象
    private static Map<String,WebSocket> onlineUserGroup=new ConcurrentHashMap<>();
    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
    //用来得到用户信息
    private String id ;
    /**
     * 连接建立成功调用的方法
     * @param session  可选的参数。session为与某个客户端的连接会话，需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(Session session,EndpointConfig endpointConfig,@PathParam("id")String  param) {
        this.session=session;
        if( param!=null) {

            this.id=param;
            logger.info("建立连接");
            onlineUserGroup.put(param, this);
//        系统发送消息：将当前用户推送给好友
            List<String> list = friendMapper.selectFriendsByUserID(param);
            Msg msg = new Msg();
            msg.setCode("200");
            msg.setSendID(param);
            msg.setMsg(param+ "上线了！");
            for (String userid : list) {
                WebSocket ws = onlineUserGroup.get(userid);
                msg.setReciveID(userid);
                if (ws != null) {
                    SendMsg(ws.session, msg);
                    logger.info("发送消息成功");
                }
            }
            //获取离线消息
            List<Chat> chats = chatMapper.getOffinformation(param);
            if (chats != null && chats.size() > 0) {
                List<String> p = new ArrayList<>();
                for (Chat chat : chats) {
                    Msg msg1 = new Msg();
                    msg1.setCode("200");
                    msg1.setSendID(chat.getSendid());
                    msg1.setReciveID(chat.getReciveid());
                    msg1.setMsg(chat.getContext());
                    SendMsg(this.session, msg);
                    p.add(chat.getChatid());
                }
                chatMapper.updateChatBatch(p);//变成在线消息
            }
        }
        logger.info("连接失败");

    }
    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        if(this.id!=null){
            onlineUserGroup.remove(this.id);
            logger.info("关闭连接");
        }
    }

    /**
     * 收到客户端消息后调用的方法
     * @param msg 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String msg,Session session) {
        if(this.id==null)
            return;
        logger.info("转发消息");
        String p []=msg.split(";");
        //将消息保存
        Chat chat=new Chat();
        chat.setChatid(CommonUtils.getUUID());
        chat.setSendid(this.id);
        chat.setReciveid(p[0]);
        chat.setContext(p[1]);
        chat.setChattime(new Date());
        Map<String,String> parms=new HashMap<>();
        parms.put("userid",this.id);
        parms.put("friendid",p[0]);
        chat.setFriendsid(friendMapper.getPrivateID(parms));
        Msg a=new Msg();
        a.setSendID(this.id);
        a.setReciveID(p[0]);
        a.setMsg(p[1]);
        if(onlineUserGroup.get(p[0])!=null){
            chat.setIslast(0);//在线消息
            //将消息发送给接受者
            SendMsg(onlineUserGroup.get(p[0]).session,a);
        }else {
            chat.setIslast(1);//离线消息
        }
        chatMapper.insert(chat);
    }
    /**
     * 发生错误时调用
     */
    @OnError
    public void onError(Session session,Throwable error) throws IOException, EncodeException {
        error.printStackTrace();
    }
    //推送消息
    public void SendMsg(Session session, Msg msg){
        try {
            session.getBasicRemote().sendObject(msg);
            logger.info("OnMessage转发成功");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (EncodeException e) {
            e.printStackTrace();
        }
    }

}